package com.gcph.zhuoba.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

import android.os.Handler;
import android.os.Message;

import com.gcph.zhuoba.main.activitys.VedioActivity;
import com.gcph.zhuoba.main.bean.Ball;
import com.gcph.zhuoba.main.bean.Desk;
import com.gcph.zhuoba.main.bean.SocketData;
import com.gcph.zhuoba.main.common.Constant;
import com.google.gson.Gson;

public class SocketClient {
	
	//连接成功和失败
	public static final int CONNECTION_SUCC = 0;
	public static final int CONNECTION_FAIL = 1;
	
	//配对成功和失败
	public static final int PAIR_SUCC = 2;
	public static final int PAIR_FAIL = 3;
	
	//采集成功和失败
	public static final int COLLECT_SUCC = 4;
	public static final int COLLECT_FAIL = 5;
	
	//选中目标球
	public static final int SELECTED_BALL = 6;
	//选中目标袋
	public static final int SELECTED_BAG = 7;
	
	//选中K球
	public static final int SELECTED_KBALL = 8;
	
	//视频上传进度
	public static final Integer VEDIO_UPLOAD_RATE = 9;
	public static final Integer VEDIO_UPLOAD_SUCCESS = 10;
	
	// 客户端输入流
	private BufferedReader in;
	// 客户端输出流
	private PrintWriter out;
	
	private Socket socket;
	//单例对象
	private static SocketClient instance;
	
	private Handler handler;

	//得到单例对象
	public static SocketClient getInstance()
	{
		if(null == instance)
		{
			instance = new SocketClient();
		}
		
		return instance;
	}
	
	public Handler getHandler()
	{
		return handler;
	}
	/**
	 * 构造方法
	 */
	private SocketClient() {}
	
	
	/**
	 * 建立连接
	 */
	public void setUpConnection(String serverIp, int serverPort,Handler _handler) {
		handler=_handler;
		Message msg = new Message();
		try {
			socket = new Socket(serverIp, serverPort);
			// 客户端输入流
			in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			// 客户端输出流
			out = new PrintWriter(socket.getOutputStream());
			
		} catch (UnknownHostException e) {
			msg.what=CONNECTION_SUCC;
			handler.sendMessage(msg);
			L.d("找不到相应的主机！");
		} catch (IOException e) {
			msg.what=CONNECTION_FAIL;
			handler.sendMessage(msg);
			L.d("建立连接失败");
		}
	}

	/**
	 * 处理接收数据
	 */
	public void handleReceive() {
		try {
			String line = null;
			Gson gson = new Gson();
			while (!(line=in.readLine()).equals("exit")) {
				Message msg = new Message();
				
				L.d("==收到line==="+line);
				SocketData socketData = gson.fromJson(line, SocketData.class);
				L.d("==收到socketData==="+socketData);
				if(null == socketData || null == socketData.getMethod())
				{
					continue;
				}
				//=========配对开始=========================
				if(socketData.getMethod().equals(Constant.SOCKET_METHOD_PAIR))
				{
					if("true".equals(socketData.getResult()))
					{
						msg.what=PAIR_SUCC;
						handler.sendMessage(msg);
						L.d("==配对成功===");
					}else
					{
						msg.what=PAIR_FAIL;
						handler.sendMessage(msg);
						continue;
					}
				}
				//=========采集开始=========================
				if(socketData.getMethod().equals(Constant.SOCKET_METHOD_COLLECT))
				{
					String data = socketData.getData();
					L.d("data=="+data);
					if("false".equals(socketData.getResult()) || null ==data)
					{
						L.d("==采集失败===");
						msg.what=COLLECT_FAIL;
						handler.sendMessage(msg);
						continue;
					}
					
					String[] balls = data.split("\\|");
					String ballStr = null;
					int ballNo = 0;
					String ballXY = null;
					float ballX = 0f;
					float ballY = 0f;
					//可进袋
					String canInBag=null;
					for (int i = 0; i < balls.length; i++) {
						ballStr = balls[i];
						ballNo = Integer.parseInt(ballStr.split(":")[0]);
						ballXY = ballStr.split(":")[1];
						if(ballStr.split(":").length>2)
						{
							canInBag=ballStr.split(":")[2];
						}else
						{
							canInBag=null;
						}
						if(ballNo>24 || ballNo<0 || (16<=ballNo && ballNo <=23))
						{
							continue;
						}
						
						ballX=Float.parseFloat(ballXY.split(",")[0]);
						ballY=Float.parseFloat(ballXY.split(",")[1]);
						
						Ball ball = new Ball();
						ball.setNo(ballNo);
						ball.setX(Constant.OFFSET_X+ballX*(Constant.imgDeskW-2*Constant.imgDeskFrame)*Constant.ratio);
						ball.setY(Constant.OFFSET_Y+ballY*(Constant.imgDeskH-2*Constant.imgDeskFrame)*Constant.ratio);
						
						if(null != canInBag)
						{
							ball.setCanIn(true);
							ball.setCanInBag(parseCanInBag(canInBag));
							Desk.canInBallList.add(ball);
						}else
						{
							ball.setCanIn(false);
							ball.setCanInBag(new int[]{});
							Desk.notCanInballList.add(ball);
						}
					}
					L.d("canInBallList="+Desk.canInBallList.toString());
					L.d("notCanInballList="+Desk.notCanInballList.toString());
					msg.what=COLLECT_SUCC;
					msg.obj=data;
					handler.sendMessage(msg);
				}
				
				//===================================上传录像开始====================================
				//上传中..
				if(socketData.getMethod().equals(Constant.SOCKET_METHOD_UPLOAD_VEDIO))
				{
					L.d("上传进度====="+socketData);
					Message msg_upload = new Message();
					String rate = socketData.getRate();
					int rateI = Integer.parseInt(rate);
					msg_upload.what=VEDIO_UPLOAD_RATE;
					msg_upload.obj=String.valueOf(rateI/2);
					
					VedioActivity.acceptRate(msg_upload);
				}
				
				//上传成功
				if(socketData.getMethod().equals(Constant.SOCKET_METHOD_UPLOAD_SUCCESS))
				{
					L.d("上传成功====fileno="+socketData.getFileno()+"====fileid="+socketData.getFileid());
					Message msg_upload = new Message();
					msg_upload.what=VEDIO_UPLOAD_SUCCESS;
					msg_upload.obj=socketData;
					VedioActivity.acceptRate(msg_upload);
				}
				
				//===================================上传截屏开始====================================
				
				
			}
			L.d("=============socket结束  =============");
			in.close();
			out.close();
		} catch (IOException e) {
			Thread.currentThread().stop();
		}finally{
			Thread.currentThread().stop();
		}
	}
	
	/**
	 * 解析可进袋
	 * @param canInBag
	 * @return
	 */
	private int[] parseCanInBag(String canInBag)
	{
		if(null == canInBag)
		{
			return null;
		}
		
		String[] canInBagArr = canInBag.split(",");
		int[] canInBagList = new int[canInBagArr.length];
		for (int i = 0; i < canInBagArr.length; i++) {
			canInBagList[i]=Integer.parseInt(canInBagArr[i]);
		}
		
		return canInBagList;
	}
	/**
	 * 消息发送
	 * @param msg
	 */
	public void send(String msg){
		//如果不是调试模式
		if(!Constant.IS_DEBUG)
    	{
			L.d("sendSocketMsg ===="+msg);
			synchronized (out) {
				out.println(msg);
				out.flush();
			}
    	}
	}
	
	/**
	 * 消息发送
	 * @param msg
	 */
	public void exit(){
		//如果不是调试模式
		if(!Constant.IS_DEBUG)
    	{
			L.d("====exit ====");
			synchronized (out) {
				out.println("{\"method\":\""+Constant.SOCKET_METHOD_EXIT+"\"}");
				out.flush();
				try {
					out.close();
					in.close();
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
    	}
	}
	
	
	/**
	 * 处理发送数据
	 * 调试用
	 * TODO
	 */
	private void handleSend() {
		class SendThread extends Thread{

			@Override
			public void run() {
				BufferedReader systemIn=new BufferedReader(new InputStreamReader(
						System.in)); 
				String line=null;
				try {
					while(true){
						line=systemIn.readLine();
						send(line);
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			
		}
		new SendThread().start();
	}
	public static void main(String[] args) {
		String result1 ="{\"data\":\"6:0.66060,0.08091|13:0.77980,0.13592|16:0.50166,0.20065|8:0.89901,0.30744|19:0.80629,0.34628|14:0.66225,0.44984|1:0.16887,0.54369|2:0.86755,0.63430|4:0.60927,0.75405|13:0.56623,0.80259\",\"method\":\"302\",\"result\":\"true\"}";
		String result2 ="{\"data\":\"4:0.43543,0.04207|10:0.93874,0.10356|19:0.97020,0.19741|13:0.49503,0.22006|15:0.88245,0.22977|14:0.64570,0.43366|7:0.78808,0.44013|6:0.61755,0.52427|9:0.75993,0.65372|15:0.96523,0.66990|3:0.62417,0.86408|2:0.64570,0.88026\",\"method\":\"302\",\"result\":\"true\"}";
	}
}